# !/usr/bin python3
# encoding: utf-8 -*-
# @file     : conftest.py
# @author   : 沙陌 Matongxue_2
# @Time     : 2023/12/26 21:48
# @Copyright: 北京码同学
import time
from typing import List

# 重写pytest内置的钩子函数，来解决在pycharm控制台上看到的中文乱码
import pytest

from api.base_api import BaseBuyerApi, BaseSellerApi, BaseManagerApi
from api.buyer.cart_apis import BuyNowApi
from api.buyer.checkout_params_apis import SetOrderPayTypeApi, SetOrderAddressIdApi
from api.buyer.create_trade_api import CreateTradeApi
from api.buyer.login_apis import BuyerLoginApi
from api.buyer.member_address_apis import AddAddressApi
from api.buyer.order_apis import OrderRogApi
from api.manager.goods_apis import GoodsBatchAuditApi
from api.manager.login_apis import ManagerLoginApi
from api.seller.goods_apis import AddGoodsApi, GoodsUnderApi, GoodsRecycleApi, GoodsDeleteApi
from api.seller.login_apis import SellerLoginApi
from api.seller.order_apis import OrderDeliveryApi, OrderPayApi
from common.db_util import DBUtil
from common.file_load import load_yaml_file, write_yaml
from common.json_util import extract_json
from common.logger import GetLogger
from common.redis_util import RedisUtil
from paths_manager import common_yaml_path, redis_yaml_path, db_yaml_path


def pytest_collection_modifyitems(config:"Config",items:List['Item']):
    # items对象是pytest收集到的所有测试用例对象
    try:
        addopts = config.getini('addopts')
        if '--dist=each' in addopts:
            # 此时说明你要用的是多进程并发，我要得到当前的worker_id
            worker_id = config.workerinput.get('workerid')
        else:
            worker_id = None
    except:
        worker_id = None
    for item in items:
        # item就代表一条用例
        if worker_id:
            item._nodeid = item._nodeid.encode('utf-8').decode('unicode-escape')+worker_id
            item.originalname = item.originalname.encode('utf-8').decode('unicode-escape')+worker_id
        else:
            item._nodeid = item._nodeid.encode('utf-8').decode('unicode-escape')

@pytest.fixture(scope='session',autouse=True)
def aalogger_init(worker_id):
    GetLogger.get_logger(worker_id=worker_id).info('日志初始化成功')


@pytest.fixture(scope='session',autouse=True)
def buyer_login(worker_id): # 注意这个worker_id是由pytest-xdist提供的，你得先安装pytest-xdist
    # 读取配置文件的基本信息
    common_info = load_yaml_file(common_yaml_path)
    usernames = common_info['buyerName'] # 得到是一个列表
    pwds = common_info['buyerPassword'] # 得到是一个列表
    # 如果没有使用多进程并发，那么worker_id等于master
    if worker_id == 'master':
        resp = BuyerLoginApi(username=usernames[0], password=pwds[0]).send()
    else:
        # gw0/gw1/gw2...
        index = int(worker_id[2:])
        resp = BuyerLoginApi(username=usernames[index], password=pwds[index]).send()
    # if worker_id=='gw0' or worker_id=='master':
    #     resp = BuyerLoginApi(username='shamo123', password='mtx9607').send()
    # elif worker_id=='gw1':
    #     resp = BuyerLoginApi(username='shamo', password='mtx9607').send()
    BaseBuyerApi.buyer_token=resp.json()['access_token']
    BaseBuyerApi.uid = resp.json()['uid']

@pytest.fixture(scope='session',autouse=True)
def seller_login():
    common_info = load_yaml_file(common_yaml_path)
    username = common_info['sellerName']
    password = common_info['sellerPassword']
    resp = SellerLoginApi(username=username,password=password).send()
    BaseSellerApi.seller_token=resp.json()['access_token']

@pytest.fixture(scope='session',autouse=True)
def manager_login():
    common_info = load_yaml_file(common_yaml_path)
    username = common_info['managerName']
    password = common_info['managerPassword']
    resp = ManagerLoginApi(username=username,password=password).send()
    BaseManagerApi.manager_token=resp.json()['access_token']

@pytest.fixture(scope='session',autouse=False)
def redis_init():
    redis_info = load_yaml_file(redis_yaml_path)
    redis_util = RedisUtil(
        host=redis_info['host'],
        port=redis_info['port'],
        pwd=redis_info['password'],
        decode_responses=False
    )
    yield redis_util

@pytest.fixture(scope='session',autouse=False)
def db_init():
    db_info = load_yaml_file(db_yaml_path)
    db_util = DBUtil(
        host=db_info['host'],
        port=db_info['port'],
        user=db_info['username'],
        password=db_info['password']
    )
    yield db_util
    db_util.close()

# 除了订单流程，是否还存在其他业务也会用到商品数据，也可能会有，因此这种比较公共型的数据，我们就定义成fixture
#
@pytest.fixture(scope='class',autouse=False)
def goods_data(db_init):
    # 添加商品
    resp = AddGoodsApi().send()
    # 提取goods_id作为后续流程使用
    goods_id = resp.json()['goods_id']
    # 管理员审核商品
    GoodsBatchAuditApi(goods_ids=[goods_id]).send()
    # 审核完成以后会产生sku_id，我们的重点就是要得到这个sku_id
    res = db_init.select(f'select sku_id from mtxshop_goods.es_goods_sku where goods_id={goods_id}')
    sku_id = res[0]['sku_id']
    yield goods_id,sku_id # 返回数据 结果是元组(2222,88888)
    # 后置处理，数据清除
    GoodsUnderApi(goods_ids=[goods_id]).send()
    GoodsRecycleApi(goods_ids=[goods_id]).send()
    GoodsDeleteApi(goods_ids=[goods_id]).send()

@pytest.fixture(scope='class',autouse=False)
def init_order_params(db_init):
    # 设置订单支付方式为货到付款
    SetOrderPayTypeApi().send()
    # 设置订单的收货地址
    # 从数据库查询当前买家用户名下的收货地址数据，如果有数据库有数据，则从数据库拿到地址id
    # 如果数据库没数据，那么我就新增一个收货地址，从响应中拿到地址id
    res = db_init.select(f'select addr_id from mtxshop_member.es_member_address where member_id={BaseBuyerApi.uid}')
    if len(res)>0:
        address_id = res[0]['addr_id']
    else:
        # 调用添加收货地址接口，造一条数据
        resp = AddAddressApi().send()
        address_id = resp.json()['addr_id']
    SetOrderAddressIdApi(address_id=address_id).send()

@pytest.fixture(scope='class',autouse=False)
def order_data(goods_data,init_order_params):
    sku_id = goods_data[1]
    BuyNowApi(sku_id=sku_id).send()
    resp = CreateTradeApi().send()
    order_sn = extract_json(resp.json(),'$..sn')
    pay_price = extract_json(resp.json(), '$..total_price')
    OrderDeliveryApi(order_sn=order_sn).send()
    OrderRogApi(order_sn=order_sn).send()
    OrderPayApi(order_sn=order_sn,pay_price=pay_price).send()
    yield sku_id,order_sn

def pytest_terminal_summary(terminalreporter,exitstatus,config):
    """统计测试结果"""
    passed = len(terminalreporter.stats.get('passed',[]))
    failed = len(terminalreporter.stats.get('failed', []))
    error = len(terminalreporter.stats.get('error', []))
    skipped = len(terminalreporter.stats.get('skipped', []))
    total = passed+failed+error+skipped
    duration = time.time()-terminalreporter._sessionstarttime
    write_yaml('result.yml',{"total":total,"passed":passed,"failed":failed,"error":error,"skipped":skipped})


if __name__ == '__main__':
    s = 'gw1'
    print(s[2:])

